home *** CD-ROM | disk | FTP | other *** search
- *=======================================================*
- * BSP-Descent: latest update 25/03/96 *
- *=======================================================*
- * Descend BSP tree, generating sectors & walls. *
- *=======================================================*
-
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- * Descend Binary Space Partitioning Tree *
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- txtlong
- *-------------------------------------------------------*
- descend_bsp:
- *-------------------------------------------------------*
- * Place start & terminator on heap and descend *
- *-------------------------------------------------------*
- move.l sp,bsp_return
- lea display_struct,a6
- move.w NumNodes,d0
- push.w #terminator
- subq.w #1,d0
- push.w d0
- bra next_node
- *-------------------------------------------------------*
- * Thread returns here when tree is exhausted *
- *-------------------------------------------------------*
- finish_tree:
- *-------------------------------------------------------*
- move.l bsp_return,sp
- rts
-
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- * [node] = [sector] -> draw this node *
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- txtlong
- *-------------------------------------------------------*
- ssector_node:
- *-------------------------------------------------------*
- * Stop drawing when [width] columns are filled *
- *-------------------------------------------------------*
- tst.w display_columns(a6)
- beq.s finish_tree
- *-------------------------------------------------------*
- * Stop drawing when last node has been popped *
- *-------------------------------------------------------*
- not.w d0
- beq.s finish_tree
- eor.w #$7FFF,d0
-
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- * Render ssector into run-buffer *
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- build_ssector:
- *-------------------------------------------------------*
- * Locate [segs] for this [ssector] *
- *-------------------------------------------------------*
- move.l display_ssectors(a6),a0
- move.w ssec_first(a0,d0.w*4),d4
- move.w ssec_segments(a0,d0.w*4),d3
- *-------------------------------------------------------*
- * Locate [linedef] & [sidedef] for first [seg] *
- *-------------------------------------------------------*
- move.l display_segs(a6),a2
- move.w d4,d2
- mulu.w #seg_len,d2
- add.l d2,a2
- move.w seg_linedef(a2),d0
- move.w seg_sidedef(a2),d2
- *-------------------------------------------------------*
- * Locate right [sidedef] for this [linedef] *
- *-------------------------------------------------------*
- move.l display_linedefs(a6),a0
- mulu.w #linedef_len,d0
- add.l d0,a0
- move.w linedef_right(a0,d2.w*2),d1
- *-------------------------------------------------------*
- * Locate [sector] for this [sidedef] *
- *-------------------------------------------------------*
- move.l display_sidedefs(a6),a0
- mulu.w #sidedef_len,d1
- add.l d1,a0
- move.w sidedef_sector(a0),d1
- *-------------------------------------------------------*
- * Set up floor & ceiling heights for this sector *
- *-------------------------------------------------------*
- move.l display_sectors(a6),a0
- mulu.w #sector_len,d1
- add.l d1,a0
- move.l a0,display_sectorptr(a6)
- *-------------------------------------------------------*
- move.w sector_floorht(a0),display_fh(a6)
- move.w sector_ceilht(a0),display_ch(a6)
- move.w sector_ftns(a0),display_ft(a6)
- move.w sector_ctns(a0),display_ct(a6)
- *-------------------------------------------------------*
- * Are we in this sector? *
- *-------------------------------------------------------*
- tst.b display_firstssec(a6)
- beq.s .skip
- clr.b display_firstssec(a6)
- *-------------------------------------------------------*
- * Set viewcone to (sector_height+player_height) *
- *-------------------------------------------------------*
- move.w display_fh(a6),d0
- add.w #player_height,d0
- add.w pho,d0
- move.w d0,display_ph(a6)
- *-------------------------------------------------------*
- * Set up segment-heap for loop *
- *-------------------------------------------------------*
- .skip: move.l d4,d2
- move.w d2,display_segbase(a6)
- move.w d3,display_segnum(a6)
- ble next_node
- *-------------------------------------------------------*
- * Process simple lighting effects (temporary!) *
- *-------------------------------------------------------*
- bsr process_lighting
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- * Render segments surrounding this ssector *
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- segment_loop:
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- * Hidden surface removal stage #1 *
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- * Is viewer on left or right side of this line? *
- *-------------------------------------------------------*
- * ((y2-y1)*(x1-Px))) => (((x2-x1)*(y1-Py)) ? *
- *-------------------------------------------------------*
- move.l display_vertices(a6),a0
- moveq #0,d0
- moveq #0,d1
- move.w linedef_from(a2),d0
- move.w linedef_to(a2),d1
- move.w vtx_x(a0,d0.l*4),d5
- move.w vtx_x(a0,d1.l*4),d6
- move.w vtx_y(a0,d0.l*4),d0
- move.w vtx_y(a0,d1.l*4),d1
- sub.w d5,d6 ; x2-x1
- sub.w d0,d1 ; y2-y1
- sub.w display_px(a6),d5 ; x1-px
- sub.w display_py(a6),d0 ; y1-py
- muls.w d6,d0 ; (x2-x1)*(y1-Py)
- muls.w d5,d1 ; (x1-px)*(y2-y1)
- cmp.l d0,d1
- bpl invisible
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- * Segment is visible *
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
- pea (a2)
- *-------------------------------------------------------*
- move.w display_segbase(a6),d0
- move.l display_segs(a6),a5
- mulu.w #seg_len,d0
- add.l d0,a5
- *-------------------------------------------------------*
- * Locate segment vertices *
- *-------------------------------------------------------*
- move.l seg_length(a5),umag
- move.w seg_distance(a5),x_offset
- move.l display_vertices(a6),a0
- moveq #0,d0
- move.w seg_from(a5),d0
- move.l a0,a1
- moveq #0,d1
- move.w seg_to(a5),d1
- lsl.l #2,d0
- lsl.l #2,d1
- add.l d0,a0 ; a+(d*4)
- add.l d1,a1 ; a+(d*4)
- *-------------------------------------------------------*
- * Fetch X1,Y1 / X2,Y2 & centre around viewpoint *
- *-------------------------------------------------------*
- lea DSPHostStat.w,a2
- lea DSPHost16.w,a3
- dspwaitwrite.0 (a2)
- move.w #projectwall_command,(a3)
- dspwaitwrite.0 (a2)
- move.w (a0)+,(a3)
- dspwaitwrite.0 (a2)
- move.w (a0)+,(a3)
- dspwaitwrite.0 (a2)
- move.w (a1)+,(a3)
- dspwaitwrite.0 (a2)
- move.w (a1)+,(a3)
- lea DSPHost32.w,a4
- dspwaitread.0 (a2)
- tst.w (a3)
- beq end_segment
- dspwaitread.0 (a2)
- move.l (a4),d3
- lsl.l #8,d3
- dspwaitread.0 (a2)
- move.l (a4),d4
- lsl.l #8,d4
- dspwaitread.0 (a2)
- move.l (a4),d5
- lsl.l #8,d5
- dspwaitread.0 (a2)
- move.l (a4),d6
- lsl.l #8,d6
- dspwaitread.0 (a2)
- move.l (a4),d1
- lsl.l #8,d1
- dspwaitread.0 (a2)
- move.l (a4),d2
- lsl.l #8,d2
- *-------------------------------------------------------*
- * Write coordinates into addwall struct *
- *-------------------------------------------------------*
- .draw: move.l d1,addwall_rz2(a6)
- move.l d2,addwall_rz1(a6)
- move.l d3,addwall_i1(a6)
- move.l d4,addwall_z1(a6)
- move.l d5,addwall_i2(a6)
- move.l d6,addwall_z2(a6)
- *-------------------------------------------------------*
- * Look up linedef for this seg *
- *-------------------------------------------------------*
- move.w seg_linedef(a5),d1
- move.l display_linedefs(a6),a0
- mulu.w #linedef_len,d1
- add.l d1,a0
- *-------------------------------------------------------*
- * Determine one or two-sided linedef *
- *-------------------------------------------------------*
- move.w linedef_attrib(a0),d0
- or.w #$100,linedef_attrib(a0)
- move.b d0,linedef_flags
- and.b #attrib_twosided,d0
- move.b d0,twosided_flag
- *-------------------------------------------------------*
- * Determine which sidedef is facing us *
- *-------------------------------------------------------*
- move.w seg_sidedef(a5),d0
- move.w linedef_right(a0,d0.w*2),d5 ; visible sidedef
- bchg #0,d0
- move.w linedef_right(a0,d0.w*2),d6 ; invisible sidedef
- *-------------------------------------------------------*
- * Look up sidedef for visible side of linedef *
- *-------------------------------------------------------*
- move.l display_sidedefs(a6),a3
- mulu.w #sidedef_len,d5
- move.l a3,a4
- add.l d5,a3
- *-------------------------------------------------------*
- * Locate [sector] on opposite side of [linedef] *
- *-------------------------------------------------------*
- tst.b twosided_flag
- beq.s .nts
- mulu.w #sidedef_len,d6
- add.l d6,a4
- move.w sidedef_sector(a4),d6 ; a+(d*30)
- move.l display_sectors(a6),a4
- mulu.w #sector_len,d6
- add.l d6,a4
- .nts: move.b #0,addwall_opaque(a6)
- tst.b twosided_flag
- beq sector_wall
-
- *-------------------------------------------------------*
- * Check for lower wall texture *
- *-------------------------------------------------------*
- lower_texture:
- *-------------------------------------------------------*
- move.l display_sectorptr(a6),a5
- move.w sidedef_ltns(a3),d0
- *-------------------------------------------------------*
- * Determine wall height *
- *-------------------------------------------------------*
- move.w sector_floorht(a4),d1
- cmp.w sector_ceilht(a5),d1
- bmi.s .clip
- move.w sector_ceilht(a5),d1
- .clip: move.w sector_floorht(a5),d2
- neg.w d1
- add.w display_ph(a6),d1
- neg.w d2
- add.w display_ph(a6),d2
- *-------------------------------------------------------*
- * Render
- *-------------------------------------------!!